module libeventd.iocp.Internal;

import
	libeventd.Types ;

version(Windows){
	extern(Windows) :
	alias BOOL function(evutil_socket_t, evutil_socket_t, PVOID, DWORD, DWORD, DWORD, LPDWORD, LPOVERLAPPED) AcceptExPtr;
	alias BOOL function(evutil_socket_t, sockaddr*, int, PVOID, DWORD, LPDWORD, LPOVERLAPPED) ConnectExPtr;
	alias void function(PVOID, DWORD, DWORD, DWORD, sockaddr**, LPINT, sockaddr**, LPINT) GetAcceptExSockaddrsPtr;
}else{
	struct event_overlapped {
		iocp_callback cb;
	}
}

version(Windows):
extern(C):
alias void function(event_overlapped*, ev_uintptr_t, ev_ssize_t, int) iocp_callback;


struct event_overlapped {
	OVERLAPPED overlapped;
	iocp_callback cb;
}

struct win32_extension_fns {
	AcceptExPtr	AcceptEx;
	ConnectExPtr	ConnectEx;
	GetAcceptExSockaddrsPtr	GetAcceptExSockaddrs;
}

struct event_iocp_port {
	HANDLE			port;
	CRITICAL_SECTION	lock;
	ev_short			n_threads;
	ev_short			shutdown;
	ev_long			ms;
	HANDLE*			threads;
	ev_short			n_live_threads;
	HANDLE*			shutdownSemaphore;
}

win32_extension_fns *event_get_win32_extension_fns() ;
void event_overlapped_init( event_overlapped *, iocp_callback cb);
 evbuffer *evbuffer_overlapped_new(evutil_socket_t fd);
evutil_socket_t _evbuffer_overlapped_get_fd( evbuffer *buf);
void _evbuffer_overlapped_set_fd( evbuffer *buf, evutil_socket_t fd);
ev_int evbuffer_launch_read( evbuffer *buf, size_t n,  event_overlapped *ol);
ev_int evbuffer_launch_write( evbuffer *buf, ev_ssize_t n,  event_overlapped *ol);
void evbuffer_commit_read( evbuffer *, ev_ssize_t);
void evbuffer_commit_write( evbuffer *, ev_ssize_t);
 event_iocp_port *event_iocp_port_launch();
ev_int event_iocp_port_associate( event_iocp_port *port, evutil_socket_t fd,ev_uintptr_t key);
ev_int event_iocp_shutdown( event_iocp_port *port, ev_long waitMsec);
ev_int event_iocp_activate_overlapped( event_iocp_port *port,  event_overlapped *o, ev_uintptr_t key, ev_uint32_t n_bytes);
event_iocp_port *event_base_get_iocp( event_base *base);
ev_int event_base_start_iocp( event_base *base);
bufferevent *bufferevent_async_new( event_base *base, evutil_socket_t fd, ev_int options);
void bufferevent_async_set_connected( bufferevent *bev);
ev_int bufferevent_async_can_connect( bufferevent *bev);
ev_int bufferevent_async_connect( bufferevent *bev, evutil_socket_t fd,	  sockaddr *sa, ev_int socklen);
